// 设计一个守护进程，每隔 2 秒获取依次系统时间，并将系统时间写入某个文件中
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <string.h>

int fd;
int flag;

void sig(int sigo) {
    // 获得当前系统时间
    time_t tm;
    time(&tm);

    char* p = ctime(&tm);

    if(flag == 0) {
        // 新建文件
        fd = open("./log.log", O_RDWR | O_CREAT | O_APPEND, 0777);
        if(fd < 0) {
            perror("open err: ");
            exit(1);
        }

        flag = 1;
    }

    // 写文件
    write(fd, p, strlen(p));

    return ;
}

int main()
{
    // 创建子进程，同时父进程需要退出
    pid_t pid = fork();
    if(pid < 0 || pid > 0) {
        exit(1);
    }
    
    // 子进程调用 setsid 函数，创建会话，并成为会长
    setsid();

    // 改变其工作目录
    // 其原本的工作目录: 当前进程启动的目录
    chdir("/home/Ay/log");

    // 重置文件掩码
    umask(0000);
    
    // 关闭标准输入、标准输出、标准出错
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    // 守护进程的核心工作
    struct sigaction act;
    act.sa_handler = sig;  
    act.sa_flags = 0;
    
    sigemptyset(&act.sa_mask);
    sigaction(SIGALRM, &act, NULL);   // 捕获信号

    // 设置闹钟
    struct itimerval tm;
    tm.it_interval.tv_sec = 2;
    tm.it_interval.tv_usec = 0;

    tm.it_value.tv_sec = 3;
    tm.it_value.tv_usec = 0;
    
    setitimer(ITIMER_REAL, &tm, NULL);
    
    while(1) {
        int size = lseek(fd, 0, SEEK_END);
        if(size > 200) {
            close(fd);
            rename("./log.log", "./log.log.bak");
            flag = 0;
        }
    }

    close(fd);

    return 0;
}

